Security News
ESLint is Now Language-Agnostic: Linting JSON, Markdown, and Beyond
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
@ampproject/toolbox-optimizer
Advanced tools
AMP Optimizer is a tool to server-side enhance the rendering performance of AMP pages. AMP Optimizer implements AMP performance best practices and supports AMP server-side-rendering. By default, it will perform the following optimizations:
amp-script
code.The performance optimizations can improve page rendering times by up to 50%. You can read more about the potential performance gains in this blog post. To give it a try, check out the online playground.
Good to know:
Install via:
npm install @ampproject/toolbox-optimizer
Minimal usage:
const AmpOptimizer = require('@ampproject/toolbox-optimizer');
const ampOptimizer = AmpOptimizer.create();
const originalHtml = `
<!doctype html>
<html ⚡>
...
</html>
`;
ampOptimizer.transformHtml(originalHtml).then((optimizedHtml) => {
console.log(optimizedHtml);
});
You can find a sample implementation here. If you're using express to serve your site, you can use the AMP Optimizer Middleware.
There's also a command line version available:
$ npx @ampproject/toolbox-cli myFile.html
Checkout the samples to learn how to customize AMP Optimizer.
The biggest performance gain results from removing the AMP boilerplate code. However, under some circumstances it's not possible to remove the boilerplate code:
if theamp-experiment
, amp-story
or amp-dynamic-css-classes
components are used (code).
if an AMP component uses the media
, sizes
or heights
attribut (documentation). A simple workaround is to replace the media
, sizes
or heights
attributes with normal CSS media queries.
if an AMP component uses the intrinsic
layout. The good news is: support for intrinsic
layout is currently work in progress.
To find out, why the AMP boilerplate could not be removed, enable verbose
mode:
// globally
const optimizer = ampOptimizer.create({
verbose: true
} );
... or for individual pages:
// per transformation
ampOptimizer.transformHtml(originalHtml, {
verbose: true
})
Applying the transformations to an AMP file consumes additional server resources. Also, since the entire file is needed to apply the transformations, it also becomes impossible to stream the response while applying it. In order to avoid server overhead, if the set of AMP files to be transformed is known in advance, transformations should be run at build time.
Most websites have a more dynamic nature though and are not able to apply the transformations statically. For such cases it is possible to run the transformations after AMP pages are rendered, e.g. in an Express middleware. In that case, to achieve best performance, it's best to cache transformed pages for subsequent requests. Caching can take place on the CDN level, on the site's internal infrastructure (eg: Memcached), or even on the server itself, if the set of pages is small enough to fit in memory.
AMP Optimizer inlines CSS styles required by AMP. To make sure, that the inlined CSS stays in sync with the latest AMP release, we recommend to re-generate pages at least once a weekOut-of-sync CSS will not break your page, but it could theoretically cause AMP components to briefly appear with the "wrong" styles, such as being visible when they should be hidden. The good news is that these glitches will only be temporary, because as soon as the AMP JS starts, it will check the inlined CSS and update it if required.
Warning: these features are experimental and might result in invalid AMP pages.
When using experimental features resulting in invalid AMP it's best to setup paired AMP mode. Paired AMP mode will add <link rel=amphtml href=${ampUrl}>
to the transformed page, were ampUrl
needs to point to the valid version of this page.
Example:
const optimizer = AmpOptimizer.create({
transformations: AmpOptimizer.TRANSFORMATIONS_PAIRED_AMP,
});
const ampFilePath = filePath.substring(1, filePath.length)
.replace('.html', '.amp.html');
const transformedHtml = await optimizer.transformHtml(html, {
// needed to calculate the `<link rel=amphtml href=${ampUrl}>`
ampUrl: ampFilePath,
});
The ampRuntimeVersion
parameter will rewrite all AMP runtime and extension imports to the specified version. For example:
https://cdn.ampproject.org/v0.js
will be replaced with:
https://cdn.ampproject.org/rtv/001515617716922/v0.js
Versioning the AMP runtime URLs has one main benefit: versioned AMP runtime URLs are served with a longer max-age than the unversioned ones. This means AMP pages served with versioned AMP runtime benefit from better browser caching.
Important: when using versioned AMP runtime URLs make sure to invalidate all caches whenever a new AMP runtime is released. This is to ensure that your AMP pages always use the latest version of the AMP runtime.
You can use @ampproject/toolbox-runtime-version to retrieve the latest version of the AMP runtime. Here is a sample to apply the optimizations including versioning the URLs:
const ampOptimizer = require('@ampproject/toolbox-optimizer');
const ampRuntimeVersion = await runtimeVersion.currentVersion();
// The input string
const originalHtml = `
<!doctype html>
<html ⚡>
...
`
// Additional options can be passed as the second argument
const optimizedHtml = await ampOptimizer.transformHtml(originalHtml, {
ampUrl: 'canonical.amp.html',
ampRuntimeVersion: ampRuntimeVersion
});
console.log(optimizedHtml);
Add placeholders for amp-img
and amp-video
posters. The placeholders are blurry versions of the corresponding original source. The blur will be displayed as the <amp-img>
is rendering, and will fade out once the element is loaded. The current requirements of appending a blurry placeholder is for the element is to be a JPEG that is either responsive or a poster for an amp-video
.
Important: blurry image placeholder computation is computationally expensive. Make sure to only use it for static or cached pages.
This transformer supports the following options:
blurredPlaceholders
: Enables blurry image placeholder generation. Default is false
.imageBasePath
: specifies a base path used to resolve an image during build.maxBlurredPlaceholders
: Specifies the max number of blurred images. Defaults to 5.blurredPlaceholdersCacheSize
: Specifies the max number of blurred images to be cached
to avoid expensive recalculation. Set to 0 if caching should be disabled. Set to -1 if
all placeholders should be cached (good for static sites). Defaults to 30.Usage:
const optimizer = AmpOptimizer.create({
// blurry image placeholders are currently not considered valid AMP
// hence it's recommended to setup paired AMP mode when enabling this feature.
transformations: AmpOptimizer.TRANSFORMATIONS_PAIRED_AMP,
blurredPlaceholders: true,
});
It's possible to rewrite the AMP framework and component imports to a different domain than cdn.ampproject.org
. These options tailor URL rewriting performed by ampOptimizer.transformHtml
:
ampUrlPrefix
: Replace https://cdn.ampproject.org/
with another origin or relative path.
Notice: The behavior of ampUrlPrefix
when used in conjunction with ampRuntimeVersion
changed beginning with version 1.1.2. Prior to 1.1.2, rtv/{rtv}/
was automatically appended to ampUrlPrefix
when ampRuntimeVersion
was specified. Since version 1.1.2, ampUrlPrefix
is not modified when ampRuntimeVersion
is also specified.
rewriteDynamicComponents
: When used in conjunction with ampUrlPrefix
, this option can be set to false
to prevent dynamic AMP components from having their URLs rewritten.
Examples:
const ampOptimizer = require('@ampproject/toolbox-optimizer');
// The input string
const originalHtml = `
<!doctype html>
<html ⚡>
...
`
// this will rewrite https://cdn.ampproject.org/v0.js to /amp/v0.js and will
// rewrite dynamic component https://cdn.ampproject.org/v0/amp-geo-0.1.js to
// /amp/v0/amp-geo-0.1.js
const optimizedHtmlA = await ampOptimizer.transformHtml(originalHtml, {
ampUrlPrefix: '/amp'
});
// this will rewrite https://cdn.ampproject.org/v0.js to /amp/v0.js and will
// not rewrite dynamic component https://cdn.ampproject.org/v0/amp-geo-0.1.js
const optimizedHtmlB = await ampOptimizer.transformHtml(originalHtml, {
ampUrlPrefix: '/amp',
rewriteDynamicComponents: false
});
// this will rewrite https://cdn.ampproject.org/v0.js to
// /amp/001515617716922/v0.js and will rewrite dynamic component
// https://cdn.ampproject.org/v0/amp-geo-0.1.js to
// https://cdn.ampproject.org/v0/rtv/001515617716922/amp-geo-0.1.js
const optimizedHtmlC = await ampOptimizer.transformHtml(originalHtml, {
ampRuntimeVersion: '001515617716922',
ampUrlPrefix: '/amp/001515617716922',
rewriteDynamicComponents: false
});
v1.1.2 (2019-10-15)
optimizer
FAQs
Server-side rendering for AMPs.
The npm package @ampproject/toolbox-optimizer receives a total of 39,394 weekly downloads. As such, @ampproject/toolbox-optimizer popularity was classified as popular.
We found that @ampproject/toolbox-optimizer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 16 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
Security News
Members Hub is conducting large-scale campaigns to artificially boost Discord server metrics, undermining community trust and platform integrity.
Security News
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.